#include "Circle.h"
#include "Define.h"

Circle::Circle(void) : Object()
{
	this->m_iRadius = 1;
	SetType(CIRCLE);
}

Circle::Circle(float posX, float posY, int radius) : Object(posX, posY)
{
	this->m_iRadius = radius;
	SetType(CIRCLE);
}

Circle::~Circle()
{

}

void Circle::Update(float frameTime)
{
	Object::Update(frameTime);

	int hasCollide = IsCollideEdge();
	if (CheckFlag(hasCollide, BOTTOM))
	{
		SetPosition(m_iPositionX, (float)(SCREEN_H - m_iRadius));
	} else if (CheckFlag(hasCollide, TOP))
	{
		SetPosition(m_iPositionX, (float)m_iRadius);
	}

	if (CheckFlag(hasCollide, RIGHT))
	{
		SetPosition((float)(SCREEN_W - m_iRadius), m_iPositionY);
	} else if (CheckFlag(hasCollide, LEFT))
	{
		SetPosition((float)m_iRadius, m_iPositionY);
	}
}

void Circle::Render()
{
	VideoDriver::GetInstance()->DrawCircle(m_iPositionX, m_iPositionY, (float)m_iRadius);
	//VideoDriver::GetInstance()->DrawRect(m_iPositionX, m_iPositionY, m_iRadius/2, m_iRadius/2);
}

void Circle::SetRadius(int i_radius)
{
	this->m_iRadius = i_radius;
}

int Circle::GetRadius()
{
	return m_iRadius;
}

bool Circle::IsInRect(int x, int y)
{
	int distance = (int)sqrt(
		pow((float)(m_iPositionX - x), 2) + pow((float)(m_iPositionY - y), 2));

	if (distance < m_iRadius)
	{
		return true;
	}
	return false;
}

void Circle::HandleTouchAction(Touch *touch)
{
	if (touch->touchState == StateMove)
	{
		/*int translateX = touch->currPosX - touch->prevPosX;
		int translateY = touch->currPosY - touch->prevPosY;
		MoveBy(translateX, translateY);*/
	}
}

bool Circle::IsCollideWithRect(float x, float y, int width, int height)
{
	//CIRCLE with RECT
	bool result = false;
	
	/*if (this->m_iPositionX + m_iRadius < x
		|| this->m_iPositionY + m_iRadius < y
		|| this->m_iPositionX - m_iRadius > x + width
		|| this->m_iPositionY - m_iRadius > y + height)
	{
		result = false;
	} else {
		result = true;
	}*/

	float posX = this->m_iPositionX;
	float posY = this->m_iPositionY;

	if (posX < x)
	{
		posX = x;
	} else if (posX > x + width)
	{
		posX = x + width;
	}

	if (posY < y)
	{
		posY = y;
	} else if (posY > y + height)
	{
		posY = y + height;
	}

	float distanceX = this->m_iPositionX - posX;
	float distanceY = this->m_iPositionY - posY;

	if (distanceX * distanceX + distanceY * distanceY < m_iRadius * m_iRadius)
	{
		result = true;
	}

	return result;
}

bool Circle::IsCollideWithObject(Object* object)
{
	int objType = object->GetType();
	if (objType == CIRCLE)
	{
		return IsCollideWithCircle((Circle*)object);
	}
	if (objType == RECTANGLE)
	{
		return object->IsCollideWithObject(this);
	}

	printf("ERROR!! Can't check collision CIRCLE with object type %d\n", objType);
	return false;
}

int Circle::IsCollideEdge()
{
	int result = 0;
	if (m_iPositionX <= m_iRadius)
	{
		result |= LEFT;
	} else if (m_iPositionX >= (int)SCREEN_W - m_iRadius)
	{
		result |= RIGHT;
	}

	if (m_iPositionY <= m_iRadius)
	{
		result |= TOP;
	} else if (m_iPositionY >= (int)SCREEN_H - m_iRadius)
	{
		result |= BOTTOM;
	}
	return result;
}

bool Circle::IsCollideWithCircle(Circle* circle)
{
	// CIRCLE with CIRCLE
	float deltaX = m_iPositionX - circle->GetPosX();
	float deltaY = m_iPositionY - circle->GetPosY();

	int circleRadius = circle->GetRadius();
	int totalRadius = m_iRadius * m_iRadius + circleRadius * circleRadius;

	if (deltaX * deltaX + deltaY * deltaY <= totalRadius)
	{
		return true;
	}
	return false;
}